package wre.logic;	

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;

import wre.Word;
import wre.data.RetortDAO;
import wre.data.WordDAO;

/**
 * The Class RetortManager.
 */
public class RetortManager {
	
	/**
	 * The main method.
	 *
	 * @param args the arguments
	 */
	public static void main(String[] args) {
		RetortManager retortManager = new RetortManager();
		System.out.print("Enter a phrase: ");
		Scanner scanner = new Scanner(System.in);
		String input = scanner.nextLine();
		try {
			System.out.println(retortManager.doRetort(input));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/** The input parser. */
	InputParser inputParser = InputParser.getInstance();
	
	/** The retort dao. */
	RetortDAO retortDAO = RetortDAO.getInstance();

	/** The word dao. */
	WordDAO wordDAO = WordDAO.getInstance();

	/**
	 * Do retort.
	 *
	 * @param input the input
	 * @return the string
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	public String doRetort(String input) throws IOException {
		if (input.matches("DELETEALL")) {
			retortDAO.deleteAll();
			wordDAO.deleteAll();
			return "deleted all";
		} else if (input.matches("DELETERETORTS")) {
			retortDAO.deleteAll();
			return "deleted all retorts";
		} else if (input.matches("DELETEWORDS")) {
			wordDAO.deleteAll();
			return "deleted all words";
		} else if (input.matches("WORDINPUT-.*")) {
			return parseWordInput(input);
		} else if (input.matches("RETORTINPUT-.*")) {
			return parseRetortInput(input);
		} else {
			List<String> inputWords = inputParser.parseInput(input);
			Map<String, Word> words = wordDAO.getWords();
			Map<Integer, Integer> matches = new HashMap<Integer, Integer>();

			for (String inputWord : inputWords) {
				if (words.containsKey(inputWord)) {
					Integer id = words.get(inputWord).getId();
					if (matches.containsKey(id)) {
						matches.put(id, matches.get(id) + 1);
					} else {
						matches.put(id, 1);
					}
				}
			}

			Integer match = getMatch(matches);
			if (null == match) {
				return "I dont understand";
			} else {
				updateMatches(match, inputWords);
				return retortDAO.getRetort(match);
			}
		}

	}

	/**
	 * Gets the match.
	 *
	 * @param matches the matches
	 * @return the match
	 */
	private Integer getMatch(Map<Integer, Integer> matches) {
		Iterator<Entry<Integer, Integer>> iterator = matches.entrySet()
				.iterator();
		Entry<Integer, Integer> entry = null;
		Entry<Integer, Integer> maxEntry = null;
		while (iterator.hasNext()) {
			entry = iterator.next();
			if ((maxEntry == null) || (maxEntry.getValue() < entry.getValue())) {
				maxEntry = entry;
			}
		}

		return null == maxEntry ? null : maxEntry.getKey();

	}

	/**
	 * Parses the retort input.
	 *
	 * @param input the input
	 * @return the string
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	private String parseRetortInput(String input) throws IOException {
		// Remove tag
		String step1 = input.substring(12);
		// Separate association|word pairs
		String[] step2 = step1.split("&amp;&amp;");
		int count = 0;
		for (String step3 : step2) {
			retortDAO.addRetort(step3);
			count++;
		}
		retortDAO.writeData();
		return "Added " + count + " retorts";
	}

	/**
	 * Parses the word input.
	 *
	 * @param input the input
	 * @return the string
	 * @throws IOException Signals that an I/O exception has occurred.
	 */
	private String parseWordInput(String input) throws IOException {
		// Remove tag
		String step1 = input.substring(10);
		// Separate association|word pairs
		String[] step2 = step1.split("&amp;&amp;");
		int count = 0;
		for (String step3 : step2) {
			// separate pairs
			String[] step4 = step3.split("\\|\\|");
			for (String word : inputParser.parseInput(step4[1])) {
				wordDAO.addWord(Integer.valueOf(step4[0]), word, false);
				count++;
			}

		}
		wordDAO.writeData();
		return "Added " + count + " words";
	}

	/**
	 * Update matches.
	 *
	 * @param match the match
	 * @param inputWords the input words
	 */
	private void updateMatches(Integer match, List<String> inputWords) {
		for (String word : inputWords) {
			wordDAO.addWord(match, word, false);
		}
	}
}
